# -*- coding: utf-8 -*-
"""
@Time ： 2024/5/23 13:28
@Auth ： 李天天
"""
import re

import pytest
from pytest_check import check
from Common.handle_log import do_log


def assert_sequential_events_log1(events_list: list, log_path):
    do_log.info("开始读取日志文件，顺序匹配事件")
    with open(log_path) as file:
        log_lines = file.readlines()
    matched_events = []
    current_event_index = 0
    # 打印当前事件名
    if current_event_index < len(events_list):
        do_log.info("当前要检索的5D日志事件名为{}".format(events_list[current_event_index]['event_name']))
    for line in log_lines:
        if current_event_index >= len(events_list):
            break
        event_pattern = events_list[current_event_index]['event_pattern']
        match = re.search(event_pattern, line)
        if match:
            matched_events.append((current_event_index, line.strip(), match.groups()))
            current_event_index += 1
            do_log.info("打印检索到的日志行：{}".format(line.strip()))
            # 如果有下一个事件，打印下一次的事件名
            if current_event_index < len(events_list):
                do_log.info("当前要检索的5D日志事件名为{}".format(events_list[current_event_index]['event_name']))

    do_log.info(f"期望的事件数量为{len(events_list)},匹配到的事件数量为{len(matched_events)}")
    # pytest.assume(len(events_list) == len(matched_events))
    check.equal(len(events_list), len(matched_events))
def assert_sequential_events_log1(events_list: list, log_path,necessary_events=3):
    do_log.info("开始读取日志文件，顺序匹配事件")
    with open(log_path) as file:
        log_lines = file.readlines()
    matched_events = []
    current_event_index = 0
    check_number=0
    line_index_must=0
    line_index=0
    log_open=True

    # 打印当前事件名

    while True :
        line=log_lines[line_index]
        if check_number < len(events_list):
            event_name = events_list[check_number]['event_name']
            event_pattern = events_list[check_number]['event_pattern']
            if log_open:
                do_log.info(
                "第{}次检测,检测事件名字为{},检测关键词为{}".format(check_number + 1, event_name, event_pattern))
                log_open=False
        if current_event_index >= len(events_list):
            break
        match = re.search(event_pattern, line)
        if match:
            matched_events.append((current_event_index, line.strip(), match.groups()))
            current_event_index += 1
            check_number += 1
            log_open=True
            do_log.info("第{}次打印检索到的日志行：{}".format(check_number,line.strip()))
            if current_event_index == necessary_events:
                do_log.info(f"必要事件验证成功。期望的必要事件数量为{necessary_events},匹配到的事件数量为{current_event_index}")

                line_index_must=line_index
            if current_event_index==necessary_events+1:
                do_log.info(
                    f"整个事件验证成功。匹配成功事件为{current_event_index},必要事件数量为{necessary_events},可选事件为1")
                break

        if not match and line_index == len(log_lines) - 1 and check_number+1 <= necessary_events:
            do_log.info("未检索到匹配的日志结果")
            do_log.info(f"验证失败。期望的必要事件数量为{necessary_events},匹配到的事件数量为{current_event_index}")
            break
        if not match and line_index == len(log_lines) - 1 and current_event_index==necessary_events and check_number+1<=len(events_list) :
            do_log.info(f"第{check_number+1}次未检索到匹配的日志结果")
            do_log.info(f"非必要事件验证失败。需要验证的非必要事件名为{event_pattern},事件名为{event_name}")
            check_number += 1
            log_open = True
            line_index=line_index_must
        if not match and line_index == len(log_lines) - 1 and check_number+1>len(events_list) :
            do_log.info(f"第{check_number+1}次未检索到匹配的日志结果")
            do_log.info(f"非必要事件验证失败。需要验证的非必要事件名为{event_pattern},事件名为{event_name}")
            break
        line_index+=1
    if necessary_events==len(events_list):
        do_log.info(f"验证通过")
        do_log.info(f"当前事件全部检测通过,匹配到的事件个数为：{necessary_events}")
        check.equal(current_event_index,necessary_events)
    else:
        do_log.info(f"当前检测通过{current_event_index}个事件,需要通过{necessary_events}个必要事件,非必要事件1个")
        check.greater(current_event_index, necessary_events)
def assert_sequential_events_log(events_list: list, log_path,necessary_events=3,model=1):
    if necessary_events>len(events_list):
        necessary_events=len(events_list)
    if model==1 and len(events_list)==necessary_events:
        do_log.info(f"模式1:开始读取日志文件，必须顺序匹配事件{len(events_list)}个")
    if model==1 and len(events_list)>necessary_events:
        do_log.info(f"模式1:开始读取日志文件，必须顺序匹配必要事件{necessary_events}个,非必要事件{len(events_list)-necessary_events}个中必须匹配命中一个")
    if model==2:
        do_log.info(f"模式2:开始读取日志文件，必须顺序匹配必要事件{necessary_events}个,非必要顺序匹配事件{len(events_list)-necessary_events}个必须全部命中")
    with open(log_path) as file:
        log_lines = file.readlines()
    matched_events = []
    current_event_index = 0
    check_number=0
    line_index_must=0
    line_index=0
    log_open=True

    # 打印当前事件名

    while True :
        line=log_lines[line_index]
        if check_number < len(events_list):
            event_name = events_list[check_number]['event_name']
            event_pattern = events_list[check_number]['event_pattern']
            if log_open:
                do_log.info(
                "第{}次检测,检测事件名字为{},检测关键词为{}".format(check_number + 1, event_name, event_pattern))
                log_open=False
        if current_event_index >= len(events_list):
            break
        match = re.search(event_pattern, line)
        if match:
            matched_events.append((current_event_index, line.strip(), match.groups()))
            current_event_index += 1
            check_number += 1
            log_open=True
            do_log.info("第{}次打印检索到的日志行为{}".format(check_number,line.strip()))
            if current_event_index == necessary_events:
                do_log.info(f"必要事件验证成功。期望的必要事件数量为{necessary_events},匹配到的事件数量为{current_event_index}")
                line_index_must=line_index
            if (current_event_index==necessary_events+1 or current_event_index==len(events_list)) and model==1:
                do_log.info(
                    f"整个事件验证成功。匹配成功事件为{current_event_index},必要事件数量为{necessary_events},可选事件为{current_event_index-necessary_events}")
                break
            if current_event_index==len(events_list):
                do_log.info(
                    f"整个事件验证成功。匹配成功事件为{current_event_index},必要事件数量为{necessary_events},必要非顺序事件为{current_event_index-necessary_events}")
                break
            if current_event_index>necessary_events and model==2:
                log_open = True
                line_index = line_index_must


        if not match and line_index == len(log_lines) - 1 and check_number+1 <= necessary_events:

            do_log.info(f"必要事件验证失败。需要验证的事件名为{event_pattern},名字为{event_name}")
            do_log.info(f"验证失败。期望的必要事件数量为{necessary_events},匹配到的事件数量为{current_event_index}")
            break
        if not match and line_index == len(log_lines) - 1 and current_event_index==necessary_events and check_number+1<=len(events_list) and model==1:
            do_log.info(f"第{check_number+1}次未检索到匹配的日志结果,事件名为{event_name}")
            do_log.info(f"非必要事件验证失败。需要验证的事件名为{event_pattern},名字为{event_name}")
            check_number += 1
            log_open = True
            line_index=line_index_must
        if not match and line_index == len(log_lines) - 1 and model==2:
            do_log.info(f"第{check_number+1}次未检索到匹配的日志结果,事件名为{event_name}")
            do_log.info(f"必要非顺序事件验证失败。必要事件正确个数为{current_event_index},必要非顺序事件正确个数为{current_event_index-necessary_events},需要通过{len(events_list)-necessary_events}个")
            break
        if not match and line_index == len(log_lines) - 1 and check_number+1>len(events_list) :
            do_log.info(f"第{check_number+1}次未检索到匹配的日志结果")
            do_log.info(f"非必要事件验证失败。需要验证的非必要事件名为{event_pattern},名字为{event_name}")
            break
        line_index+=1

    if model==1 and necessary_events<len(events_list):
        do_log.info(f"当前检测通过{current_event_index}个事件,需要通过{necessary_events}个必要事件,非必要事件1个")
        check.greater(current_event_index, necessary_events)
    else:
        do_log.info(f"当前检测通过{current_event_index}个事件,需要通过{len(events_list)}个必要事件,")
        check.equal(current_event_index, len(events_list))

def assert_exist_events_log(events_list: list, log_path):
    do_log.info("开始读取日志文件为一个字符串")
    with open(log_path, 'r', encoding='utf-8') as file:
        log_content = file.read()

    for pattern in events_list:
        start_pattern = pattern["start_pattern"]
        start_index = pattern.get("start_index")
        event_pattern = pattern["event_pattern"]
        end_pattern = pattern["end_pattern"]
        end_index = pattern.get("end_index")
        expect = pattern["expect"]
        expect_info = "存在" if expect else "不存在"
        do_log.info(
            f"当前是要在 {start_pattern}和 {end_pattern}之间检索有没有 {event_pattern} ,期望的结果是 {expect_info}")
        if start_pattern == "START_OF_LOG":
            start_index = 0
        else:
            start_matches = [match for match in re.finditer(start_pattern, log_content, re.MULTILINE)]
            if not start_matches:
                do_log.error("开始事件没有匹配到，异常情况直接跳出当前检索校验")
                check.is_true(start_matches)
                continue
            start_match = start_matches[start_index]
            start_index = start_match.end()
        #
        if end_pattern == "END_OF_LOG":
            end_index = len(log_content)
        else:
            end_matches = [match for match in re.finditer(end_pattern, log_content[start_index:], re.MULTILINE)]
            # end_matches = [match for match in re.finditer(end_pattern, log_content, re.MULTILINE)]
            if not end_matches:
                do_log.error("结束事件没有匹配到，异常情况直接跳出当前检索校验")
                check.is_true(end_matches)
                continue
            end_match = end_matches[end_index]
            end_index = start_index + end_match.start()

        # 检查start_pattern和end_pattern之间是否包含event_pattern
        # do_log.info("检查start_pattern和end_pattern之间是否包含event_pattern")
        event_found = bool(re.search(event_pattern, log_content[start_index:end_index], re.MULTILINE))
        if event_found:
            do_log.info("检索结果为 存在")
        else:
            do_log.info("检索结果为 不存在")
        if expect:
            check.is_true(re.search(event_pattern, log_content[start_index:end_index], re.MULTILINE))
        else:
            check.is_false(re.search(event_pattern, log_content[start_index:end_index], re.MULTILINE))
